package protocol

import (
	"encoding/binary"
	"encoding/json"
	"fmt"
	"log"
	"math"

	"github.com/sirupsen/logrus"
)

// AnalogValue represents the structure of an analog value packet
type AnalogValue struct {
	SystemType    byte   // 系统类型标志
	SystemAddress byte   // 系统地址
	ComponentType byte   // 部件类型
	ComponentAddr uint32 // 部件地址
	AnalogType    byte   // 模拟量类型
	// AnalogValue   int16  // 模拟量值
	// 协议修改
	AnalogValue []byte // 模拟量值

}

func parseFloat32LittleEndian(bytes []byte) float32 {
	if len(bytes) != 4 {
		panic("Input must be exactly 4 bytes")
	}

	bits := binary.LittleEndian.Uint32(bytes)
	return math.Float32frombits(bits)
}

// ParseAnalogValuePacket parses a byte slice into an AnalogValue
// 信息体+时间
func ParseAnalogValuePacket(data []byte) (*AnalogValue, error) {
	if len(data) < 18 { // Check minimum length for a single analog value packet
		return nil, fmt.Errorf("data too short")
	}
	av := &AnalogValue{
		SystemType:    data[0],
		SystemAddress: data[1],
		ComponentType: data[2],
		ComponentAddr: binary.LittleEndian.Uint32(data[3:7]),
		AnalogType:    data[7],
		//AnalogValue:   int16(binary.LittleEndian.Uint16(data[8:10])),
		// 协议修改
		AnalogValue: data[8:12],
	}
	return av, nil
}

// ConvertToJSON converts AnalogValue struct to JSON format
func ConvertToJSON(av *AnalogValue) (string, error) {
	jsonData, err := json.Marshal(av)
	if err != nil {
		return "", err
	}
	return string(jsonData), nil
}

func IAMain() {
	// Example packet data (truncated for clarity; should include all fields)
	packetData := []byte{0x0C, 0x00, 0x97, 0x01, 0x00, 0x00, 0x00, 0x97, 0x9C, 0x01}

	av, err := ParseAnalogValuePacket(packetData)
	if err != nil {
		log.Fatalf("Error parsing packet: %v", err)
	}
	jsonOutput, err := ConvertToJSON(av)
	if err != nil {
		log.Fatalf("Error converting to JSON: %v", err)
	}

	fmt.Println(jsonOutput)
}

// 处理每一个模拟量值，这里的data为信息对象，有多个
// 信息体+时间标签为16字节 新协议18字节
func HandleAnalogValues(data []byte, count int) (map[string]interface{}, error) {
	var mapData map[string]interface{}
	for i := 0; i < count; i++ {
		if len(data) < 18 { // 每个模拟量值需要至少16字节
			logrus.Errorf("Not enough data for analog value %d", i+1)
			return nil, fmt.Errorf("not enough data for analog value %d", i+1)
		}
		// av, err := ParseAnalogValuePacket(data[:16])
		// 协议修改
		av, err := ParseAnalogValuePacket(data[:18])
		if err != nil {
			logrus.Errorf("Failed to parse analog value %d: %v", i+1, err)
			return nil, fmt.Errorf("failed to parse analog value %d: %v", i+1, err)
		}

		key, value, err := ProcessAnalogValue(av)
		if err != nil {
			logrus.Warnf("Failed to process analog value: %v", err)
		} else {
			if mapData == nil {
				mapData = make(map[string]interface{})
			}
			mapData[key] = value
		}

		// 移动到下一个模拟量值
		// 协议修改16-18
		data = data[18:]
	}
	// // 如果key是hydraulic_pressure_kpa，把个位数和两位小数提出来并除以1000，加到hydraulic_pressure_mpa后
	// if value, ok := mapData["hydraulic_pressure_kpa"].(float64); ok {
	// 	// 提取个位数和两位小数
	// 	kpaStr := strconv.FormatFloat(value, 'f', 2, 64)
	// 	kpaFloat, _ := strconv.ParseFloat(kpaStr, 64)
	// 	fractionalPart := kpaFloat - float64(int(kpaFloat))

	// 	// 将提取的部分除以1000
	// 	fractionalPartInMpa := fractionalPart / 1000

	// 	// 检查mapData["hydraulic_pressure_mpa"]是否存在并转换为float64
	// 	if existingMpa, ok := mapData["hydraulic_pressure_mpa"].(float64); ok {
	// 		// 如果存在，加上新的部分
	// 		mapData["hydraulic_pressure_mpa"] = existingMpa + fractionalPartInMpa
	// 	}
	// }
	return mapData, nil
}

func roundToFourDecimals(value float64) float64 {
	return math.Round(value*10000) / 10000
}

// 处理单个模拟量值
func ProcessAnalogValue(av *AnalogValue) (string, float64, error) {
	var value float64
	var unit string
	var key string

	switch av.AnalogType {
	case 150: // 液位 m
		key = "liquid_level"
		// value = float64(av.AnalogValue) * 0.01
		// 协议修改
		value = math.Round(float64(parseFloat32LittleEndian(av.AnalogValue))*10000) / 10000

		unit = "m"
	case 151: // 液压 MPa
		key = "hydraulic_pressure_mpa"
		// value = float64(av.AnalogValue) * 0.01
		// 协议修改
		value = math.Round(float64(parseFloat32LittleEndian(av.AnalogValue))*10000) / 10000
		unit = "MPa"
	case 152: // 液压 kPa
		key = "hydraulic_pressure_kpa"
		// value = float64(av.AnalogValue) * 0.01
		// 协议修改
		value = math.Round(float64(parseFloat32LittleEndian(av.AnalogValue))*10000) / 10000
		unit = "kPa"
	case 160: // 温度
		key = "temperature"
		// value = float64(av.AnalogValue) * 0.1
		// 协议修改
		value = math.Round(float64(parseFloat32LittleEndian(av.AnalogValue))*10) / 10
		unit = "°C"
	case 190: // 电压
		key = "voltage"
		// value = float64(av.AnalogValue) * 0.01
		// 协议修改
		value = math.Round(float64(parseFloat32LittleEndian(av.AnalogValue))*100) / 100
		unit = "V"
	case 230: // 信号强度
		key = "signal"
		// value = float64(av.AnalogValue)
		// 协议修改
		value = math.Round(float64(parseFloat32LittleEndian(av.AnalogValue))*1) / 1
		unit = "dBm"
	default:
		logrus.Warnf("Unknown analog type: %d", av.AnalogType)
		return "", 0, fmt.Errorf("unknown analog type: %d", av.AnalogType)
	}

	logrus.Infof("Analog value: System Type[系统类型标志]: %d, Component Type[部件类型]: %d, Component Address[部件地址]: %d, Type[模拟量类型]: %d, Value[值]: %.2f %s",
		av.SystemType, av.ComponentType, av.ComponentAddr, av.AnalogType, value, unit)
	return key, value, nil
}
